/*
 * Copyright 2016 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.optaplanner.examples.taskassigning.domain;

import org.optaplanner.core.api.domain.entity.PlanningEntity;
import org.optaplanner.core.api.domain.variable.InverseRelationShadowVariable;
import org.optaplanner.examples.common.domain.AbstractPersistable;

@PlanningEntity
public abstract class TaskOrEmployee extends AbstractPersistable {

    // Shadow variables
    // 反向关系的影子变量，这里只有这一个变量
    // 作用是，建立双向关系，因为之前的那个previousXXX是向前指的，这里加上这个反向的影子变量在需要从前向后找的时候就很方便了，
    // 在输出排程结果的时候，用这个从一条链的锚开始，用这个变量一步步向后找，直接就能把整条链输出出来
    // 关于这个变量在时间链模式中起的作用理解：https://zhuanlan.zhihu.com/p/59189465
    // 在双向关系中，影子端（=从属端）使用此属性（而不是其他任何属性）声明它对于哪个PlanningVariable（=主端）而言是影子。
    // 也就是说，在这里，TaskOrEmployee用nextTask属性来声明它对于previousTaskOrEmployee是影子，两个变量正好是反着的，一个在链中从前向后指，一个从后向前指
    @InverseRelationShadowVariable(sourceVariableName = "previousTaskOrEmployee")
    protected Task nextTask;

    public TaskOrEmployee() {
    }

    public TaskOrEmployee(long id) {
        super(id);
    }

    public Task getNextTask() {
        return nextTask;
    }

    public void setNextTask(Task nextTask) {
        this.nextTask = nextTask;
    }

    /**
     * @return sometimes null
     */
    public abstract Integer getEndTime();

    /**
     * @return sometimes null
     */
    public abstract Employee getEmployee();

}
